home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 22 / AMUG_22-4.ISO / Files IV / Prog / S / StuLib 2.6.sit / StuLib / Source Code ƒ / FloaterUtils ƒ / FloaterUtils.c / FloaterUtils.c
Encoding:
Text File  |  1983-03-14  |  15.9 KB  |  678 lines  |  [TEXT/CWIE]

  1. //    FloaterUtils
  2. //    ©1996 Stuart Snaddon
  3. //
  4. //    This unit handles stuff to do with windows and floaters in the mac interface.
  5. //    Uses 'wind' resources to initialise and describe windows.
  6. //
  7.  
  8. #include <Types.h>
  9. #include "FloaterUtils.h"
  10.  
  11. // ** Structs
  12.  
  13. typedef struct {
  14.     OSType        creator;
  15.     OSType        kind;
  16.     short        resID;
  17.     char            isFloating;
  18.     char            fill1;
  19.     char            isDialog;
  20.     char            fill2;
  21.     char            canMultiple;
  22.     char            fill3;
  23.     char            isResizable;
  24.     char            fill4;
  25.     char            canDock;
  26.     char            fill5;
  27.     } WindStyle, *WindStylePtr, **WindStyleHandle;
  28.  
  29. typedef struct windnode
  30.     {
  31.     WindowPtr        window;
  32.     WindStyle            info;
  33.     char                shown;
  34.     struct windnode    *next;
  35.     } WindNode, *WindNodePtr;
  36.         
  37. WindNodePtr        head = NULL;
  38.  
  39. WindNodePtr        GetNodeFromWindow(WindowPtr theWindow);
  40. WindNodePtr        GetNodeFromResID(short theResID);
  41.  
  42. typedef struct dockTag {
  43.     OSType        kind;
  44.     void            *func;
  45.     struct dockTag    *next;
  46. } DockDesc, *DockPtr, **DockHandle;
  47.  
  48. DockPtr            dockHead = NULL; // uh... huh huh hrm he
  49.  
  50. short    FWIsInDockRegion(WindowPtr theWindow, Point thePoint);
  51. void        *FWGetDockingRoutine(OSType theDockType);
  52. // routine format:
  53. //        short dockRoutine(WindowPtr floater, WindowPtr mainWindow);
  54. //    returns    true = docked successfully
  55. //            false = didn't dock
  56. pascal void myDragHook(void);
  57.  
  58. // ***********************************************************************************
  59.  
  60. void        FWAddDockingRoutine(OSType theDockType, void *theDockRoutine) {
  61.     DockPtr    temp;
  62.     
  63.     if (FWGetDockingRoutine(theDockType))
  64.         return;
  65.     
  66.     temp = (DockPtr)NewPtr(sizeof(DockDesc));
  67.     temp->kind = theDockType;
  68.     temp->func = theDockRoutine;
  69.     temp->next = dockHead;
  70.     dockHead = temp;
  71. }
  72.  
  73. // ***********************************************************************************
  74.  
  75. void        *FWGetDockingRoutine(OSType theDockType) {
  76.     DockPtr    temp = dockHead;
  77.     
  78.     while (temp != NULL) {
  79.         if (temp->kind == theDockType)
  80.             return temp->func;
  81.         temp = temp->next;
  82.     }
  83.     
  84.     return NULL;
  85. }
  86.  
  87. // ***********************************************************************************
  88.  
  89. short    FWIsInDockRegion(WindowPtr theWindow, Point thePoint) {
  90.     WindowPtr    frontWin = FWFrontWindow();
  91.     Rect            theRect = frontWin->portRect;
  92.  
  93.     if (canDock(theWindow)) {
  94.         if ((GetWinKind(frontWin) == GetWinCreator(theWindow))
  95.             || ((OSType)frontWin == GetWinCreator(theWindow))) {
  96.                         
  97.             theRect.bottom = 20;
  98.             if (PtInRect(thePoint, &theRect))
  99.                 return true;
  100.         }
  101.     }
  102.         
  103.     return false;
  104. }
  105.  
  106. // ***********************************************************************************
  107.  
  108. WindNodePtr    GetNodeFromWindow(WindowPtr theWindow)
  109.     {
  110.     extern WindNodePtr        head;
  111.     WindNode    *p,*q;
  112.     
  113.     p=head;
  114.     q=0;
  115.     while (p!=q)
  116.         if (p->window==theWindow)     q=p;
  117.         else                        p=p->next;
  118.     return p;
  119.     }
  120.     
  121. // ***********************************************************************************
  122.  
  123. WindNodePtr    GetNodeFromResID(short theResID)
  124.     {
  125.     extern WindNodePtr        head;
  126.     WindNode *p,*q;
  127.     
  128.     p=head;
  129.     q=0;
  130.     while (p!=q)
  131.         if (p->info.resID==theResID)    q=p;
  132.         else                        p=p->next;
  133.     return p;
  134.     }
  135.     
  136. // ***********************************************************************************
  137.  
  138. WindowPtr    FWOpenWindow(short theResID)
  139.     {
  140.     extern WindNodePtr    head;
  141.     WindNode            *temp;
  142.     WindStyleHandle    theRes;
  143.     WindowPtr        behindWin;
  144.     
  145.     theRes=(WindStyleHandle)GetResource('wind',theResID);
  146.     HLock((Handle)theRes);
  147.     if (((*theRes)->canMultiple!=0) || (GetNodeFromResID((*theRes)->resID)==0)) {
  148.         temp=(WindNodePtr)NewPtrClear(sizeof(WindNode));
  149.         if ((temp!=0) && (theRes!=0)) {
  150.             BlockMove(*theRes,&(temp->info),sizeof(WindStyle));
  151.             temp->shown=true;
  152.             temp->next=head;
  153.             head=temp;
  154.             if (temp->info.isFloating) {
  155.                 behindWin=(WindowPtr)-1;
  156.             } else {
  157.                 behindWin=FWLastFloater();
  158.                 if (FWFrontWindow() != 0)
  159.                     HiliteWindow(FWFrontWindow(),false);
  160.                 }
  161.             if (behindWin==nil)
  162.                 behindWin=(WindowPtr)-1;
  163.             if (temp->info.isDialog) {
  164.                 temp->window=GetNewDialog(temp->info.resID,0,behindWin);
  165.             } else {
  166.                 temp->window=GetNewCWindow(temp->info.resID,0,behindWin);}
  167.             if (FWFrontWindow() != 0) {
  168.                 HiliteWindow(FWFrontWindow(),true);}
  169.             UpdateFloaters();
  170.             HUnlock((Handle)theRes);
  171.             return (temp->window);
  172.             }
  173.         } else {
  174.             FWSelectWindow((GetNodeFromResID((*theRes)->resID))->window);
  175.             HUnlock((Handle)theRes);
  176.             return (GetNodeFromResID((*theRes)->resID)->window);
  177.         }
  178.     return noErr;
  179.     }
  180.  
  181. // ***********************************************************************************
  182.     
  183. void        FWCloseWindow(WindowPtr theWindow)
  184.     {
  185.     extern WindNodePtr        head;
  186.     WindNode    *p,*q,*p0;
  187.     
  188.     if (theWindow != 0) {
  189.         p0=head;
  190.         p=0;
  191.         q=0;
  192.         while (p0!=q) {
  193.             if (p0->window==theWindow) {
  194.                 q=p0;
  195.             } else {
  196.                 p=p0;
  197.                 p0=p0->next;
  198.                 }
  199.             }
  200.         if ((p0!=0) && (p0==q)) {
  201.             if (isDialog(theWindow)) {
  202.                 DisposDialog(theWindow);
  203.             } else {
  204.                 DisposeWindow(theWindow);}
  205.             if (p==0) {
  206.                 head=p0->next;
  207.             } else {
  208.                 p->next=p0->next;}
  209.             DisposePtr((Ptr)p0);
  210.             if (FWFrontWindow() != 0)
  211.                 HiliteWindow(FWFrontWindow(),true);
  212.             UpdateFloaters();
  213.             }
  214.         }
  215.     }
  216.  
  217. // ***********************************************************************************
  218. WindowPtr    g_hookWindow;
  219. short        g_successful = false;
  220. RgnHandle        g_dragRgn;
  221. PenState        g_pen;
  222.  
  223. pascal void myDragHook(void) {
  224.     GrafPtr        savePort;
  225.     static         Point localPt;
  226.     short        (*func)(WindowPtr floatWin, WindowPtr mainWin);
  227.     RgnHandle        localRgn = NewRgn();
  228.     
  229.     CopyRgn(g_dragRgn, localRgn);
  230.     
  231.     GetPort(&savePort);
  232.     SetPort(FWFrontWindow());
  233.     GetMouse(&localPt);
  234.     SetPort(savePort);
  235.     GetPenState(&g_pen);
  236.  
  237.     if (FWIsInDockRegion(g_hookWindow, localPt)) {
  238.     
  239.         FrameRgn(localRgn);
  240.         
  241.         func = FWGetDockingRoutine(GetWinKind(g_hookWindow));
  242.         
  243.         if (func)
  244.             g_successful = func(g_hookWindow, FWFrontWindow());
  245.             
  246.         SetPort(savePort);
  247.         SetPenState(&g_pen);
  248.         FrameRgn(localRgn);
  249.         }
  250. }
  251.  
  252. void        FWDragWindow(WindowPtr theWindow, Point startPt, Rect *bounds)
  253.     {
  254.     GrafPtr    screenPort,savePort;
  255.     RgnHandle    theRgn;
  256.     Point        globDist,dist;
  257.     long        result, oldDragHook;
  258.     
  259.     GetPort(&savePort);
  260.     theRgn=NewRgn();
  261.     CopyRgn(((WindowPeek)theWindow)->strucRgn,theRgn);
  262.     screenPort=(GrafPtr)NewPtr(sizeof(GrafPort));
  263.     OpenPort(screenPort);
  264.     SetPort(screenPort);
  265.     SetPt(&globDist,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.left,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.top);
  266.  
  267.     oldDragHook = *((long *)0x09F6);
  268.     *((long *)0x09F6) = (long)myDragHook;
  269.     g_hookWindow = theWindow;
  270.     g_successful = false;
  271.     g_dragRgn = theRgn;
  272.     
  273.     result=DragGrayRgn(theRgn,startPt,bounds,bounds,0,0);
  274.  
  275.     *((long *)0x09F6) = oldDragHook;
  276.     
  277.     dist.v=HiWord(result);
  278.     dist.h=LoWord(result);
  279.     ClosePort(screenPort);
  280.     DisposePtr((Ptr)screenPort);
  281.     SetPort(savePort);
  282.     if (g_successful)  // managed to dock fine, so trash this window
  283.         FWCloseWindow(theWindow);
  284.     else {
  285.         if (result != 0x80008000) {
  286.             SetPt(&globDist,globDist.h+dist.h,globDist.v+dist.v);
  287.             MoveWindow(theWindow,globDist.h,globDist.v,false);}
  288.         FWSelectWindow(theWindow);}
  289.     }
  290.  
  291. // ***********************************************************************************
  292.  
  293. void        FWSelectWindow(WindowPtr theWindow)
  294.     {
  295.     WindowPtr    behindWin,foreWindow;
  296.     
  297.     foreWindow=FWFrontWindow();
  298.     if (theWindow!=0) {
  299.         if ((isFloating(theWindow)) && (FWFrontFloater()!=theWindow)) {
  300.             HiliteWindow(FWFrontFloater(),false);
  301.             BringToFront(theWindow);
  302.             HiliteWindow(theWindow,true);
  303.             }
  304.         else if ((!isFloating(theWindow))&&(foreWindow!=theWindow)) {
  305.             HiliteWindow(foreWindow,false);
  306.             behindWin=FWLastFloater();
  307.             if (behindWin==0) {
  308.                 BringToFront(theWindow);
  309.             } else {
  310.                 SendBehind(theWindow,behindWin);}
  311.             HiliteWindow(theWindow,true);
  312.             UpdateFloaters();
  313.             }}
  314.     }
  315.  
  316. // ***********************************************************************************
  317.  
  318. WindowPtr    FWLastFloater(void)
  319.     {
  320.     WindowPtr    theWindow,endWindow;
  321.     
  322.     theWindow = FrontWindow();
  323.     endWindow = nil;
  324.     while (theWindow != nil) {
  325.         if (isFloating(theWindow) && isVisible(theWindow))
  326.             endWindow = theWindow;
  327.         theWindow = (WindowPtr)(((WindowPeek)theWindow)->nextWindow);}
  328.     return endWindow;
  329.     }
  330.  
  331. // ***********************************************************************************
  332.  
  333. WindowPtr    FWFrontFloater(void)
  334.     {
  335.     WindowPtr    theWindow;
  336.     
  337.     theWindow=FrontWindow();
  338.     if (isFloating(theWindow)) {
  339.         return theWindow;}
  340.     else {
  341.         return nil;}
  342.     }
  343.  
  344. // ***********************************************************************************
  345.  
  346. WindowPtr    FWFrontWindow(void)
  347.     {
  348.     WindowPtr    theWindow;
  349.     
  350.     theWindow=FrontWindow();
  351.     while ((theWindow!=0) && (isFloating(theWindow)))
  352.         theWindow=(WindowPtr)(((WindowPeek)theWindow)->nextWindow);
  353.     return theWindow;
  354.     }
  355.  
  356. // ***********************************************************************************
  357.  
  358. char        isFloating(WindowPtr theWindow)
  359.     {
  360.     if (theWindow!=0) {
  361.         return (GetNodeFromWindow(theWindow)->info.isFloating);
  362.     } else {
  363.         return 0;}
  364.     }
  365.  
  366. // ***********************************************************************************
  367.  
  368. char        isResizable(WindowPtr theWindow)
  369.     {
  370.     if (theWindow!=0) {
  371.         return (GetNodeFromWindow(theWindow)->info.isResizable);
  372.     } else {
  373.         return 0;}
  374.     }
  375.  
  376. // ***********************************************************************************
  377.  
  378. char        isDialog(WindowPtr theWindow)
  379.     {
  380.     if (theWindow!=0) {
  381.         return (((WindowPeek)theWindow)->windowKind==dialogKind);
  382.     } else {
  383.         return 0;}
  384.     }
  385.  
  386. // ***********************************************************************************
  387.  
  388. char        isVisible(WindowPtr theWindow)
  389.     {
  390.     if (theWindow!=0) {
  391.         return (GetNodeFromWindow(theWindow)->shown);
  392.     } else {
  393.         return false;}
  394.     }
  395.  
  396. // ***********************************************************************************
  397.  
  398. char        canMultiple(WindowPtr theWindow)
  399.     {
  400.     return (GetNodeFromWindow(theWindow)->info.canMultiple);
  401.     }
  402.  
  403. // ***********************************************************************************
  404.  
  405. char        canDock(WindowPtr theWindow)
  406.     {
  407.     return (GetNodeFromWindow(theWindow)->info.canDock);
  408.     }
  409.  
  410. // ***********************************************************************************
  411.  
  412. OSType    GetWinCreator(WindowPtr theWindow)
  413.     {
  414.     return (GetNodeFromWindow(theWindow)->info.creator);
  415.     }
  416.  
  417. // ***********************************************************************************
  418.  
  419. OSType    GetWinKind(WindowPtr theWindow)
  420.     {
  421.     return (GetNodeFromWindow(theWindow)->info.kind);
  422.     }
  423.  
  424. // ***********************************************************************************
  425.  
  426. void        SetWinCreator(WindowPtr theWindow, OSType newCreator)
  427.     {
  428.     (GetNodeFromWindow(theWindow)->info.creator)=newCreator;
  429.     }
  430.  
  431. // ***********************************************************************************
  432.  
  433. void        SetWinKind(WindowPtr theWindow, OSType newKind)
  434.     {
  435.     (GetNodeFromWindow(theWindow)->info.kind)=newKind;
  436.     }
  437.  
  438. // ***********************************************************************************
  439.  
  440. void        SetCanMultiple(WindowPtr theWindow, char canMultiple)
  441.     {
  442.     (GetNodeFromWindow(theWindow)->info.canMultiple)=canMultiple;
  443.     }
  444.  
  445. // ***********************************************************************************
  446.  
  447. void        SetCanDock(WindowPtr theWindow, char canDock)
  448.     {
  449.     (GetNodeFromWindow(theWindow)->info.canDock)=canDock;
  450.     }
  451.  
  452. // ***********************************************************************************
  453.  
  454. void        SetFloating(WindowPtr theWindow, char     isFloating)
  455.     {
  456.     GetNodeFromWindow(theWindow)->info.isFloating=isFloating;
  457.     FWSelectWindow(theWindow);
  458.     }
  459.  
  460. // ***********************************************************************************
  461.  
  462. void        SetResizable(WindowPtr theWindow, char isResizable)
  463.     {
  464.     GetNodeFromWindow(theWindow)->info.isResizable=isResizable;
  465.     }
  466.  
  467. // ***********************************************************************************
  468.  
  469. void        SuspendWindows(char suspended)
  470.     {
  471.     WindowPtr    foreWindow;
  472.     
  473.     if ((foreWindow=FWFrontWindow()) == nil) return;
  474.  
  475.     if (suspended)
  476.         HideAllFloaters();
  477.     else
  478.         UpdateFloaters();
  479.     if (foreWindow!=0)
  480.         HiliteWindow(foreWindow,!suspended);
  481.     }
  482.  
  483. // ***********************************************************************************
  484.  
  485. void        UpdateFloaters(void)
  486.     {
  487.     extern WindNodePtr        head;
  488.     WindowPtr    foreWindow;
  489.     WindNode        *p;
  490.     
  491.     foreWindow=FWFrontWindow();
  492.     p=head;
  493.     while (p!=0) {
  494.         if (isFloating(p->window) && (p->info.creator=='appl')) {
  495.             ShowFloater(p->window);
  496.         } else if (isFloating(p->window) && (p->info.creator==GetNodeFromWindow(foreWindow)->info.kind)) {
  497.             ShowFloater(p->window);
  498.         } else if (isFloating(p->window) && (p->info.creator==(OSType)foreWindow)) {
  499.             ShowFloater(p->window);
  500.         } else if (isFloating(p->window)) {
  501.             HideFloater(p->window);}
  502.         p=p->next;
  503.         }
  504.     }
  505.  
  506. // ***********************************************************************************
  507.  
  508. void        HideFloater(WindowPtr theWindow)
  509.     {
  510.     WindNode        *node;
  511.     Point            globDist;
  512.     
  513.     node=GetNodeFromWindow(theWindow);
  514.     SetPt(&globDist,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.left,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.top);
  515.     if ((node->shown) && (globDist.h != 0) && (globDist.v != 0)) {
  516.         node->shown=false;
  517.         MoveWindow(theWindow,globDist.h+5000,globDist.v+5000,false);
  518.         SendBehind(theWindow,0);
  519.         }
  520.     }
  521.  
  522. // ***********************************************************************************
  523.  
  524. void        HideAllFloaters(void)
  525.     {
  526.     extern WindNodePtr        head;
  527.     WindNode    *p;
  528.     
  529.     p=head;
  530.     while (p!=0) {
  531.         if (isFloating(p->window))
  532.             HideFloater(p->window);
  533.         p=p->next;
  534.         }
  535.     }
  536.  
  537. // ***********************************************************************************
  538.  
  539. void        ShowFloater(WindowPtr theWindow)
  540.     {
  541.     WindNode        *node;
  542.     Point            globDist;
  543.     
  544.     node=GetNodeFromWindow(theWindow);
  545.     SetPt(&globDist,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.left,(*((WindowPeek)theWindow)->contRgn)->rgnBBox.top);
  546.     if (!(node->shown)) {
  547.         node->shown=true;
  548.         MoveWindow(theWindow,globDist.h-5000,globDist.v-5000,false);
  549.         BringToFront(theWindow);
  550.         }
  551.     }
  552.  
  553. // ***********************************************************************************
  554.  
  555. void        ShowCertainFloaters(OSType theCreator)
  556.     {
  557.     extern WindNodePtr        head;
  558.     WindNode        *p;
  559.     
  560.     p=head;
  561.     while (p!=0) {
  562.         if ((isFloating(p->window)) && (p->info.creator==theCreator))
  563.             ShowFloater(p->window);
  564.         p=p->next;
  565.         }
  566.     }
  567.  
  568. // ***********************************************************************************
  569.  
  570. char        ExistsAllready(OSType theKind)
  571.     {
  572.     extern WindNodePtr        head;
  573.     WindNode        *p,*q;
  574.     
  575.     p=head;
  576.     q=0;
  577.     while (p!=q) {
  578.         if (p->info.kind==theKind){
  579.                             q=p;
  580.         } else {
  581.                             p=p->next;}
  582.         }
  583.     return (char)(p!=0);
  584.     }
  585.  
  586. // ***********************************************************************************
  587.  
  588. WindowPtr    GetWindowWithKind(OSType theKind)
  589.     {
  590.     extern WindNodePtr        head;
  591.     WindNode        *p,*q;
  592.     
  593.     p=head;
  594.     q=0;
  595.     while (p!=q) {
  596.         if (p->info.kind==theKind) {
  597.             q=p;
  598.         } else {
  599.             p=p->next;}
  600.         }
  601.     if (p!=0) {
  602.         return (p->window);}
  603.     else {
  604.         return nil;}
  605.     }
  606.  
  607. // ***********************************************************************************
  608.  
  609. char        ExistsWindowWithTitle(Str255 theTitle)
  610.     {
  611.     extern WindNodePtr        head;
  612.     WindNode    *p,*q;
  613.     Str255                realTitle;
  614.     
  615.     p=head;
  616.     q=0;
  617.     while (p!=q) {
  618.         GetWTitle(p->window,realTitle);
  619.         if (EqualString(realTitle,theTitle,false,false)) {
  620.             q=p;
  621.         } else {
  622.             p=p->next;}
  623.         }
  624.     return (char)(p!=0);
  625.     }
  626.  
  627. // ***********************************************************************************
  628.  
  629. WindowPtr    GetWindowWithTitle(Str255 theTitle)
  630.     {
  631.     extern WindNodePtr        head;
  632.     WindNode    *p,*q;
  633.     Str255                realTitle;
  634.     
  635.     p=head;
  636.     q=0;
  637.     while (p!=q) {
  638.         GetWTitle(p->window,realTitle);
  639.         if (EqualString(realTitle,theTitle,false,false)) {
  640.             q=p;
  641.         } else {
  642.             p=p->next;}
  643.         }
  644.     if (p!=0) {
  645.         return (p->window);}
  646.     else {
  647.         return nil;}
  648.     }
  649.  
  650. // ***********************************************************************************
  651.  
  652. char        FWDialogSelect(EventRecord *theEvent, WindowPtr *theWindow, short *itemHit)
  653.     {
  654.     Point        localPt;
  655.     short    iType;
  656.     Handle    iHandle;
  657.     Rect        iRect;
  658.     
  659.     if (((WindowPeek)theWindow)->windowKind==dialogKind)
  660.         if (FindWindow(theEvent->where,theWindow)==inContent) {
  661.             localPt=theEvent->where;
  662.             SetPort(*theWindow);
  663.             GlobalToLocal(&localPt);
  664.             *itemHit=FindDItem(*theWindow,localPt)+1;
  665.             if (*itemHit>0) {
  666.                 GetDItem(*theWindow,*itemHit,&iType,&iHandle,&iRect);
  667.                 if ((iType<8) && (iType>3)) {
  668.                     if (FindControl(localPt,*theWindow,&(ControlHandle)iHandle)!=0)
  669.                         return (char)(TrackControl((ControlHandle)iHandle,localPt,nil)!=0);
  670.                 } else {
  671.                      return (char)true;
  672.                     }
  673.                 }
  674.             }
  675.     return false;
  676.     }
  677.  
  678. // ***********************************************************************************